#include<iostream>

using namespace std;

    //创建一个只能在堆上开辟空间的类
    //方法一、析构函数私有化
//class HeapOnly
//{
//public:
//    void Destroy()
//    {
//        delete this;
//    }
//private:
//    ~HeapOnly()
//    {
//        //...
//    }
//    HeapOnly(const HeapOnly& hp) = delete;
//    HeapOnly& operator=(const HeapOnly& hp) = delete;
//
//};
//
//int main()
//{
//    //由于析构函数私有，所以无法在main函数内delete释放
//    //只能在类里面提供一个接口来进行释放
//    HeapOnly* hp1 = new HeapOnly; 
//    hp1->Destroy();
//    return 0;
//}

  //方法二、将构造函数禁止

//class HeapOnly
//{
//public:
//    static HeapOnly* CreateObj()
//    {
//        return new HeapOnly;
//    }
//private:
//    HeapOnly()
//    {
//        //...
//    }
//    HeapOnly(const HeapOnly& hp) = delete;
//    HeapOnly& operator=(const HeapOnly& hp) = delete;
//
//};
//
//int main()
//{
//    HeapOnly* hp1 = HeapOnly::CreateObj();
//    return 0;
//}

//设计一个类只能在栈区创建对象

class  StackOnly
{
public:
    static StackOnly CreateObj()
    {
        return StackOnly();
    }

private:
    StackOnly()
        :_a(0)
    {
    }

private:
    
    int _a;
};

class NoInstance
{
public:
    static NoInstance GetInstance()
    {
        return NoInstance();
    }
private:
    NoInstance()
    {}
};

//使用final关键字修饰类，表示该类不能被继承·
class A final
{
    //...
};

//饿汉模式
namespace hungry
{
    class Singleton
    {
        static Singleton& GetInstance()
        {
            return m_instance;
        }
    private:
        //构造函数私有
        Singleton()
        {}
        //防拷贝
        Singleton(const Singleton& st);
        Singleton& operator=(Singleton& st);
        
        static Singleton m_instance;
        
    };

   Singleton Singleton::m_instance;
}

namespace lazy
{
    class Singleton
    {
    public:
        static Singleton* GetInstance()
        {
            if(nullptr == m_pInstance)
                m_pInstance = new Singleton();
            return m_pInstance;
        }
        
        class GC
        {
            public:
                ~GC()
                {
                    delete Singleton::m_pInstance;
                }
        };
        
        static GC gc;
            
    private:
        //构造函数私有、防拷贝
        Singleton()
        {}

        Singleton(const Singleton& st) = delete;
        Singleton& operator=(const Singleton& st) = delete;
    
        static Singleton* m_pInstance;
    };
    Singleton* Singleton::m_pInstance = nullptr;
    Singleton::GC gc;

}
